Skip to content

Refresh union language reference for .NET 11 preview 5#54198

Draft
BillWagner wants to merge 8 commits into
dotnet:mainfrom
BillWagner:preview-5-union-updates
Draft

Refresh union language reference for .NET 11 preview 5#54198
BillWagner wants to merge 8 commits into
dotnet:mainfrom
BillWagner:preview-5-union-updates

Conversation

@BillWagner
Copy link
Copy Markdown
Member

@BillWagner BillWagner commented Jun 5, 2026

Fixes #53522
Fixes #54001

In .NET 11, preview 5, unions have had an update:

First, more features are available like the TryGet pattern, and member providers.
Second, there have been some consistency updates regarding how pattern matching works.

Finally, while here, fix an issue where the sample showed the language feature, but it wasn't a good design.


Internal previews

📄 File 🔗 Preview link
docs/csharp/language-reference/builtin-types/union.md Union types (C# reference)
docs/csharp/language-reference/compiler-messages/union-declaration-errors.md Resolve errors and warnings for union type declarations
docs/csharp/language-reference/operators/patterns.md "Patterns - Pattern matching using the is and switch expressions."
docs/csharp/whats-new/csharp-15.md What's new in C# 15

Add the changes to union types that shipped with .NET 11 preview 5.
The `not` pattern is an additional exception to the rule to apply to its value. Not patterns apply to the union itself.
The runtime types are now included in .NET 11 preview 5.
Member providers ship with this preview.
The original sample was not a good one because it really didn't match the design as stated.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refreshes the C# union language reference and related snippets for .NET 11 Preview 5, reflecting newly available runtime support and updated union/pattern-matching behavior. It also replaces the previous “OneOrMore” body-members sample with a more appropriate design.

Changes:

  • Updates union documentation to reflect Preview 5 runtime support, union member providers, TryGetValue semantics, and pattern-matching details.
  • Enables and updates union snippets to exercise member providers and replaces the “OneOrMore” sample with a Length example.
  • Updates related “What’s new” and pattern-matching reference pages for the new behavior.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docs/csharp/whats-new/csharp-15.md Updates the union feature note to reflect Preview 5 runtime support.
docs/csharp/language-reference/operators/patterns.md Updates union pattern exceptions list to include the not pattern.
docs/csharp/language-reference/builtin-types/union.md Main refresh of union reference content, including member providers and updated pattern-matching guidance.
docs/csharp/language-reference/builtin-types/snippets/unions/RuntimePolyfill.cs Removes the polyfill now that Preview 5 includes the runtime types.
docs/csharp/language-reference/builtin-types/snippets/unions/Program.cs Runs the member provider scenario as part of the snippet entrypoint.
docs/csharp/language-reference/builtin-types/snippets/unions/MemberProvider.cs Implements the member provider example and scenario used by the docs/snippet harness.
docs/csharp/language-reference/builtin-types/snippets/unions/BodyMembers.cs Replaces the “OneOrMore” example with a Length union demonstrating additional members.

Comment thread docs/csharp/language-reference/builtin-types/union.md
Comment thread docs/csharp/language-reference/builtin-types/union.md Outdated
BillWagner and others added 3 commits June 5, 2026 13:57
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Proofread and grammar check
@BillWagner
Copy link
Copy Markdown
Member Author

@adegeo @gewarren This is also ready to review, although I am keeping it in draft state until .NET 11 preview 5 ships. That should fix the build errors. After I verify that, I'd want to merge this promptly.

Copy link
Copy Markdown
Contributor

@gewarren gewarren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few minor suggestions.


:::code language="csharp" source="snippets/unions/NullHandling.cs" id="NullHandling":::

This situation can arise when the `union` expression is the default value, or isn't definitely assigned, as shown in the preceding sample.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This situation can arise when the `union` expression is the default value, or isn't definitely assigned, as shown in the preceding sample.
This situation can arise when the `union` expression is the default value or isn't definitely assigned, as shown in the preceding sample.

The compiler converts a `union` declaration to a `struct` declaration. The struct is marked with the `[System.Runtime.CompilerServices.Union]` attribute and implements the `IUnion` interface. It includes a public constructor and an implicit conversion for each case type along with a `Value` property. That generated form is opinionated. It's always a struct, always boxes value-type cases, and always stores contents as `object?`.

When you need different behavior - such as a class-based union, a custom storage strategy, interop support, or if you want to adapt an existing type - you can create a union type manually.
You might need different behavior if you want to adapt an existing type, create a class-based union, use a custom storage strategy, or need interop support. You can create a union type manually.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You might need different behavior if you want to adapt an existing type, create a class-based union, use a custom storage strategy, or need interop support. You can create a union type manually.
You might need different behavior if you want to adapt an existing type, create a class-based union, or use a custom storage strategy, or if you need interop support. You can create a union type manually.

```

Union types first appeared in .NET 11 Preview 2. In early .NET 11 previews, the `UnionAttribute` and `IUnion` interface aren't included in the runtime, so you must declare them in your project. Later .NET 11 preview versions include these runtime types. Also, some features from the [proposal specification](~/_csharplang/proposals/unions.md) aren't yet implemented, including *union member providers*. Those features are coming in future previews.
The runtime includes the `UnionAttribute` and `IUnion` types beginning with Preview 5. Some features from the [proposal specification](~/_csharplang/proposals/unions.md) aren't yet implemented. Those features are coming in future previews.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The runtime includes the `UnionAttribute` and `IUnion` types beginning with Preview 5. Some features from the [proposal specification](~/_csharplang/proposals/unions.md) aren't yet implemented. Those features are coming in future previews.
The runtime includes the `UnionAttribute` and `IUnion` types beginning with .NET 11 Preview 5. Some features from the [proposal specification](~/_csharplang/proposals/unions.md) aren't yet implemented. Those features are coming in future previews.

Copy link
Copy Markdown
Contributor

@adegeo adegeo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a quick run through and it looks OK, apart from gewarren's issues and the compiler problem :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[C# 15-Fundamentals and reference]: Update on unions OneOrMore Example is wrong

4 participants